<template>
  <div class="response-section">
    <div class="section-header">
      <h3>Response</h3>
      <div class="response-info" v-if="transaction.response">
        <n-tag v-if="transaction.response.tlsVersion" class="tls-version" size="small">{{ transaction.response.tlsVersion }}</n-tag>
        <n-tag class="http-version" size="small">Remote: {{ transaction.response.remoteHttpVersion }}</n-tag>
        <n-tag class="body-size" size="small">Body: {{ formatBytes(transaction.response.bodySize) }}</n-tag>
        <n-tag :type="getStatusType(transaction.response.statusCode)" size="small">
          {{ transaction.response.statusCode }}
        </n-tag>
      </div>
    </div>
    
    <div v-if="!transaction.response" class="no-response">
      <n-empty description="暂无响应数据" />
    </div>
    
    <n-tabs v-else type="line" size="small" class="detail-tabs">
      <n-tab-pane name="headers" tab="Headers">
        <div class="tab-content">
          <n-button 
            class="copy-btn" 
            size="tiny" 
            @click="copyHeaders" 
            :disabled="Object.keys(transaction.response.headers).length === 0"
            circle
            quaternary
          >
            <template #icon>
              <n-icon :component="CopyOutline" />
            </template>
          </n-button>
          <div v-if="Object.keys(transaction.response.headers).length === 0" class="no-data">
            无 Headers
          </div>
          <div v-else>
            <div 
              v-for="[key, value] in Object.entries(transaction.response.headers)" 
              :key="key" 
              class="header-item"
            >
              <strong>{{ key }}:</strong> {{ value }}
            </div>
          </div>
        </div>
      </n-tab-pane>
      
      <n-tab-pane name="cookies" tab="Cookies">
        <div class="tab-content">
          <n-button 
            class="copy-btn" 
            size="tiny" 
            @click="copyCookies" 
            :disabled="Object.keys(transaction.response.cookies || {}).length === 0"
            circle
            quaternary
          >
            <template #icon>
              <n-icon :component="CopyOutline" />
            </template>
          </n-button>
          <div v-if="Object.keys(transaction.response.cookies || {}).length === 0" class="no-data">
            无 Cookies
          </div>
          <div v-else>
            <div 
              v-for="[key, value] in Object.entries(transaction.response.cookies || {})" 
              :key="key" 
              class="cookie-item"
            >
              <strong>{{ key }}:</strong> {{ value }}
            </div>
          </div>
        </div>
      </n-tab-pane>
      
      <n-tab-pane name="raw" tab="Raw">
        <div class="tab-content">
          <n-button 
            class="copy-btn" 
            size="tiny" 
            @click="copyRaw"
            circle
            quaternary
          >
            <template #icon>
              <n-icon :component="CopyOutline" />
            </template>
          </n-button>
          <pre class="raw-content">{{ getResponseRaw() }}</pre>
        </div>
      </n-tab-pane>
      
      <n-tab-pane name="body" tab="Body">
        <div class="tab-content body-tab">
          <div v-if="!transaction.response.body" class="no-body">
            无响应体
          </div>
          <div v-else class="body-section">
            <BodyViewer :body="transaction.response.body" :headers="transaction.response.headers" />
          </div>
        </div>
      </n-tab-pane>
    </n-tabs>
  </div>
</template>

<script setup lang="ts">
import { useMessage } from 'naive-ui';
import CopyOutline from '@vicons/ionicons5/Copy';
import type { HttpTransaction } from '../types/index';
import BodyViewer from './BodyViewer.vue';
import { copyToClipboard, formatObjectForCopy } from '../utils/clipboard';

interface Props {
  transaction: HttpTransaction;
}

const props = defineProps<Props>();
const message = useMessage();

const getStatusType = (statusCode: number) => {
  if (statusCode >= 200 && statusCode < 300) return 'success';
  if (statusCode >= 300 && statusCode < 400) return 'warning';
  if (statusCode >= 400 && statusCode < 500) return 'error';
  if (statusCode >= 500) return 'error';
  return 'default';
};

const formatBytes = (bytes: number) => {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

const getResponseRaw = () => {
  if (!props.transaction?.response) return '';
  
  const { response } = props.transaction;
  let raw = `${response.remoteHttpVersion} ${response.statusCode}\n`;
  
  // 添加响应头
  Object.entries(response.headers).forEach(([key, value]) => {
    raw += `${key}: ${value}\n`;
  });
  
  // 添加响应体
  if (response.body) {
    raw += `\n${response.body}`;
  }
  
  return raw;
};

// 复制功能
async function copyHeaders() {
  if (!props.transaction?.response) return;
  const text = formatObjectForCopy(props.transaction.response.headers);
  const success = await copyToClipboard(text);
  if (success) {
    message.success('Headers 已复制到剪贴板');
  } else {
    message.error('复制失败');
  }
}

async function copyCookies() {
  if (!props.transaction?.response) return;
  const text = formatObjectForCopy(props.transaction.response.cookies || {});
  const success = await copyToClipboard(text);
  if (success) {
    message.success('Cookies 已复制到剪贴板');
  } else {
    message.error('复制失败');
  }
}

async function copyRaw() {
  const text = getResponseRaw();
  const success = await copyToClipboard(text);
  if (success) {
    message.success('Raw 数据已复制到剪贴板');
  } else {
    message.error('复制失败');
  }
}
</script>

<style scoped lang="less">
.response-section {
  height: 100%;
  padding: 12px 16px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border-color);
  box-sizing: border-box;
  
  .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border-color);
    flex-shrink: 0;
    height: 44px; /* 固定高度 */
    
    h3 {
      margin: 0;
      font-size: 14px;
      font-weight: 600;
      color: var(--text-color);
    }
    
    .response-info {
      display: flex;
      align-items: center;
      gap: 8px;
      
      .http-version,
      .body-size,
      .tls-version {
        font-size: 12px;
        color: #666;
      }
      
      .tls-version {
        background-color: #e8f5e8;
        color: #2d8659;
        border-color: #52c41a;
      }
    }
  }
  
  .detail-tabs {
    flex: 1;
    min-height: 0;
    /* 计算高度: 100% - section-header(44px + 12px margin) */
    height: calc(100% - 56px);

    --n-tab-gap: 8px;
  }
  
  .no-response {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-tertiary);
    border-radius: 4px;
  }
  
  .tab-content {
    padding: 12px;
    height: 100%;
    overflow-y: auto;
    background: var(--bg-tertiary);
    border-radius: 4px;
    border: 1px solid var(--border-color);
    box-sizing: border-box;
    position: relative;

    .copy-btn {
      position: absolute;
      top: 8px;
      right: 8px;
      z-index: 10;
      background: var(--bg-color);
      border: 1px solid var(--border-color);
      opacity: 0.7;
      transition: all 0.2s ease;
      
      &:hover {
        opacity: 1;
        background: var(--primary-color-suppl);
        border-color: var(--primary-color);
      }
      
      &:disabled {
        opacity: 0.3;
        cursor: not-allowed;
      }
    }
    
    &.body-tab {
      padding: 0;
      
      .body-section {
        height: 100%;
        padding: 12px;
        box-sizing: border-box;
      }
    }
    
    .header-item,
    .cookie-item {
      padding: 4px 0;
      border-bottom: 1px solid var(--border-color);
      color: var(--text-color);
      font-size: 12px;
      
      &:last-child {
        border-bottom: none;
      }
      
      strong {
        color: #1890ff;
        margin-right: 8px;
        font-weight: 600;
      }
    }
    
    .raw-content {
      margin: 0;
      padding: 12px;
      background: var(--bg-color);
      border-radius: 4px;
      border: 1px solid var(--border-color);
      white-space: pre-wrap;
      word-break: break-all;
      font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
      font-size: 12px;
      line-height: 1.4;
      color: var(--text-color);
      height: 100%;
      overflow-y: auto;
      box-sizing: border-box;
    }
    
    .no-data,
    .no-body {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100px;
      color: #999;
    }
  }
}

.detail-tabs {
  :deep(.n-tabs) {
    flex: 1;
    display: flex;
    flex-direction: column;
    height: 100%;
    
    .n-tabs-nav {
      background: var(--bg-color);
      border-bottom: 1px solid var(--border-color);
      padding: 0 4px;
      min-height: 32px;
      flex-shrink: 0;
    }
    
    .n-tabs-tab {
      border-radius: 4px 4px 0 0;
      margin: 0 1px;
      font-weight: 500;
      font-size: 12px;
      padding: 6px 12px;
      color: var(--text-color);
    }
    
    .n-tabs-tab--active {
      background: var(--primary-color-suppl);
      color: var(--primary-color);
    }
  }

  :deep(.n-tabs-content) {
    flex: 1;
    overflow: hidden;
    background: var(--bg-color);
    display: flex;
    flex-direction: column;
  }

  :deep(.n-tab-pane) {
    height: 100%;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
}
</style> 